import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JLabel;
import javax.swing.ListSelectionModel;

import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JRadioButton;


public class AdminPurchasesPanel extends JPanel {
	private static final long serialVersionUID = 5799910983931587393L;
	
	private JTable table;
	private ArrayList<PurchasesRow> purchase_list;
	private JScrollPane scrolly;
	private String user;

	private final DatabaseInfo db_info;
	private JRadioButton cinema_purchases;
	private JRadioButton my_purchases;
	private boolean is_cinema;
	private String my_cinema;
	private JLabel ticketNum;
	private JLabel revenue;
	private JLabel total;
	private JLabel totalTicketsSold;
	private JLabel lblName;
	private JLabel lblFavoriteGenre;
	private JLabel genre;
	private JLabel name;
	private JComponent lblCinema;
	private Component cinema_name;

	/**
	 * Create the panel.
	 */
	public AdminPurchasesPanel(DatabaseInfo the_db_info) {
		db_info = the_db_info;
		user = the_db_info.getAccountID();
		my_cinema = getQuery("SELECT members.adminFor FROM members WHERE members.accountID='"
				+ db_info.getAccountID() + "';", true);

		setLayout(null);

		total = new JLabel("Total Ticket Revenue:");
		total.setFont(new Font("Tahoma", Font.PLAIN, 15));
		total.setBounds(26, 327, 170, 19);
		add(total);

		String rev = getQuery(
				"SELECT SUM(ticketPrice) " +
						"FROM purchases, tickets " +
						"WHERE purchases.cName = tickets.cName " +
						"AND purchases.ticketType = tickets.ticketType AND purchases.cName ='"
						+ my_cinema + "';", true);
		if (rev.equals("null")) {
			rev = "0";
		}

		revenue = new JLabel("$" + rev);
		revenue.setFont(new Font("Tahoma", Font.PLAIN, 15));
		revenue.setBounds(175, 327, 133, 19);
		add(revenue);

		totalTicketsSold = new JLabel("Total Tickets Sold:");
		totalTicketsSold.setFont(new Font("Tahoma", Font.PLAIN, 15));
		totalTicketsSold.setBounds(300, 327, 133, 19);
		add(totalTicketsSold);

		ticketNum = new JLabel(getQuery("SELECT COUNT(purchaseNum) " +
				"FROM purchases " +
				"WHERE cName ='" + my_cinema + "';", true));
		ticketNum.setFont(new Font("Tahoma", Font.PLAIN, 15));
		ticketNum.setBounds(423, 327, 133, 19);
		add(ticketNum);

		JLabel lblPurchaseHistory = new JLabel("Purchase History");
		lblPurchaseHistory.setFont(new Font("Tahoma", Font.BOLD, 23));
		lblPurchaseHistory.setBounds(295, 24, 244, 38);
		add(lblPurchaseHistory);


		cinema_purchases = new JRadioButton("Cinema Purchases");
		cinema_purchases.setBounds(585, 24, 156, 23);
		cinema_purchases.addActionListener(new RadioListener());
		cinema_purchases.setSelected(true);
		is_cinema = true;
		PurchasesRow.is_cinema = true;
		add(cinema_purchases);

		my_purchases = new JRadioButton("My Purchases");
		my_purchases.setBounds(585, 43, 156, 23);
		my_purchases.addActionListener(new RadioListener());
		add(my_purchases);

		ButtonGroup group = new ButtonGroup();
		group.add(cinema_purchases);
		group.add(my_purchases);

		JButton btnRefresh = new JButton("Refresh");
		btnRefresh.setBounds(655, 330, 112, 23);
		add(btnRefresh);
		btnRefresh.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				refreshTable();
				setLabelQueries();
			}
		});

		lblName = new JLabel("Name: ");
		lblName.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblName.setBounds(10, 28, 45, 14);
		add(lblName);

		name = new JLabel(getQuery("SELECT members.name FROM members WHERE members.accountID='"
				+ db_info.getAccountID() + "';", true));
		name.setFont(new Font("Tahoma", Font.BOLD, 11));
		name.setBounds(44, 28, 100, 14);
		add(name);

		lblCinema = new JLabel("Cinema:");
		lblCinema.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblCinema.setBounds(10, 48, 70, 14);
		add(lblCinema);

		cinema_name = new JLabel(my_cinema);
		cinema_name.setFont(new Font("Tahoma", Font.BOLD, 11));
		cinema_name.setBounds(54, 48, 229, 14);
		add(cinema_name);

		lblFavoriteGenre = new JLabel("Favorite Genre:");
		lblFavoriteGenre.setFont(new Font("Tahoma", Font.PLAIN, 11));
		lblFavoriteGenre.setBounds(10, 48, 100, 14);

		genre = new JLabel(getQuery("SELECT members.favGenre FROM members WHERE members.accountID='"
				+ db_info.getAccountID() + "';", true));
		genre.setFont(new Font("Tahoma", Font.BOLD, 11));
		genre.setBounds(89, 48, 150, 14);

		createAddScrollPane(new JTable());
		refreshTable();
	}

	private void setLabelQueries() {
		String rev = null;
		if (is_cinema) {
			rev = getQuery(
					"SELECT SUM(ticketPrice) " +
							"FROM purchases, tickets " +
							"WHERE purchases.cName = tickets.cName " +
							"AND purchases.ticketType = tickets.ticketType AND purchases.cName ='"
							+ my_cinema + "';", true);
			if (rev.equals("null")) {
				rev = "0";
			}

			revenue.setText("$" + rev);

			ticketNum.setText(getQuery(
					"SELECT COUNT(purchaseNum) " +
							"FROM purchases " +
							"WHERE cName ='" + my_cinema + "';", true));
			
			total.setText("Total Ticket Revenue:");
			totalTicketsSold.setText("Total Tickets Sold:");
			total.setBounds(26, 327, 170, 19);
			totalTicketsSold.setBounds(300, 327, 133, 19);
			add(lblCinema);
			add(cinema_name);
			remove(lblFavoriteGenre);
			remove(genre);
		} else {
			rev = getQuery(
					"SELECT SUM(ticketPrice) " +
							"FROM purchases, tickets " +
							"WHERE purchases.cName = tickets.cName " +
							"AND purchases.ticketType = tickets.ticketType AND purchases.accountID ='"
							+ user + "';", true);
			if (rev.equals("null")) {
				rev = "0";
			}

			ticketNum.setText(getQuery(
					"SELECT COUNT(purchaseNum) " +
							"FROM purchases " +
							"WHERE accountID ='" + user + "';", true));

			revenue.setText("$" + rev);
			
			total.setText("Total Spent:");
			totalTicketsSold.setText("Total Tickets Bought:");
			total.setBounds(90, 327, 140, 19);
			totalTicketsSold.setBounds(280, 327, 170, 19);
			add(lblFavoriteGenre);
			add(genre);
			remove(lblCinema);
			remove(cinema_name);
		}
	}

	private void createAddScrollPane(JTable table) {
		scrolly = new JScrollPane(table);
		scrolly.setBounds(10, 70, 761, 250);
		add(scrolly);
	}

	/**
	 * Executes a given query and returns the results;
	 * @param query The query to execute;
	 * @return The result of the query. Returns <code>null</code> if there
	 * 			was an exception thrown.
	 */
	private String getQuery(String query, boolean parse) {
		Db db = Db.getDb();
		String result = null;

		try {
			if (!parse)
				result = db.executeQuery(db_info.server, db_info.database, query, 
						db_info.user_name, db_info.password);
			else {
				result = db.executeQuery2(db_info.server, db_info.database, query, 
						db_info.user_name, db_info.password);
				result = result.replace("@", "");
			}

		} catch (Exception e1) {
			System.out.println(e1.getMessage());
			e1.printStackTrace();
		}

		return result;
	}


	private ArrayList<String> splitRowStrings(String the_data) {
		ArrayList<String> ret = new ArrayList<String>();

		while(0 < the_data.length()) {
			int io = the_data.indexOf('\r');
			String s;
			if(0 > io)
				s = the_data.trim();
			else
				s = the_data.substring(0,io).trim();

			ret.add(s);

			if(0 > io)
				break;
			the_data = the_data.substring(io,the_data.length()).trim();
		}
		return ret;
	}

	private String[] splitString(String header_string) {
		header_string = header_string.trim();
		String[] temp = header_string.split("\t");

		int valid_count = 0;
		for(int i = 0 ; i < temp.length ; i++) {
			temp[i] = temp[i].trim();
			if(0 < temp[i].length())
				valid_count++;
		}

		String[] ret = new String[valid_count];
		int j = 0;
		for(int i = 0 ; i < temp.length ; i++) {
			if(0 < temp[i].length())
				ret[j++] = temp[i];
		}
		return ret;
	}

	private String convertTitle(final String str) {
		if(str.equals("purchaseNum")) return "Purchase ID";
		else if(str.equals("cName")) return "Cinema";
		else if(str.equals("title")) return "Movie";
		else if(str.equals("ticketType")) return "Ticket Type";
		else if(str.equals("accountID")) return "Account ID";
		else if(str.equals("ticketPrice")) return "Ticket Price";

		return str; //default
	}


	private String formQuery(boolean is_row_count) {
		String query = null;
		if (is_cinema) {
			if (is_row_count)
				query = "SELECT COUNT(purchaseNum) FROM purchases WHERE cName ='"
						+ my_cinema + "';";
			else
				query = "SELECT purchases.purchaseNum, purchases.accountID, purchases.title, purchases.ticketType, tickets.ticketPrice FROM purchases, tickets WHERE purchases.ticketType = tickets.ticketType AND purchases.cName = tickets.cName AND purchases.cName ='"
						+ my_cinema + "';";
		} else {
			if (is_row_count)
				query = "SELECT COUNT(purchaseNum) FROM purchases WHERE accountID ='"
						+ user + "';";
			else
				query = "SELECT purchases.purchaseNum, purchases.cName, purchases.title, purchases.ticketType, tickets.ticketPrice FROM purchases, tickets WHERE purchases.ticketType = tickets.ticketType AND purchases.cName = tickets.cName AND purchases.accountID ='"
						+ user + "';";
		}
		return query;
	}

	private void refreshTable() {
		final int column_count = 5;

		String result = getQuery(formQuery(false), false);

		if(null != result) {
			String header_line = result.substring(0, result.indexOf('\r'));

			String[] column_names = splitString(header_line);
			for(int i = 0 ; i < column_names.length ; i++)
				column_names[i] = convertTitle(column_names[i]);

			result = result.substring(result.indexOf('\r'),result.length()).trim();
			ArrayList<String> row_strings = splitRowStrings(result);
			Object[][] table_data = new Object[row_strings.size()][column_count];
			purchase_list = new ArrayList<PurchasesRow>();

			int x = 0, y = 0;
			
			for(String s : row_strings) {
				x = 0;
				PurchasesRow row = new PurchasesRow(s);
				purchase_list.add(row);
				table_data[y][x++] = row.getPurchaseNum();
				if (PurchasesRow.is_cinema) {
					table_data[y][x++] = row.getAccountID();
				}
				if (!PurchasesRow.is_cinema) {
					table_data[y][x++] = row.getCName();
				}
				table_data[y][x++] = row.getTitle();
				table_data[y][x++] = row.getTicketType();
				table_data[y][x++] = row.getTicketPrice();
				y++;
			}

			table = new JTable(table_data, column_names);
			table.getColumnModel().getColumn(0).setPreferredWidth(40);
			if (PurchasesRow.is_cinema)
				table.getColumnModel().getColumn(1).setPreferredWidth(104);
			if (!PurchasesRow.is_cinema) 
				table.getColumnModel().getColumn(1).setPreferredWidth(250);
			table.getColumnModel().getColumn(2).setPreferredWidth(220);
			table.getColumnModel().getColumn(3).setPreferredWidth(72);
			table.getColumnModel().getColumn(4).setPreferredWidth(72);
			table.setFillsViewportHeight(true);
			table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

			this.remove(scrolly);
			createAddScrollPane(table);
		}
	}

	private class RadioListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JRadioButton button = ((JRadioButton) e.getSource());
			if (button.isSelected() && button.getText().equals("Cinema Purchases")) {
				is_cinema = true;
				PurchasesRow.is_cinema = true;
				refreshTable();
				setLabelQueries();
			} else if (button.isSelected() && button.getText().equals("My Purchases")) {
				is_cinema = false;
				PurchasesRow.is_cinema = false;
				refreshTable();
				setLabelQueries();
			}

		}
	}
}
